基础
1. 简介
.NET简介
Microsoft新一代多语言的开发平台,用于构建和运行应用程序。
.NET程序开发和运行的环境主要由两部分组成:
- 公共语言运行时
- 类库
CLS 公共语言规范 目的:跨语言
Common Language Specification.
定义了.NET平台上运行的语言所必须支持的规范,用以避免不同语言特性产生的错误,实现语言间互操作。
CLR 公共语言运行库 目的:优化,跨平台
Common Language Runtime.
程序运行环境,负责内存分配、垃圾收集、安全检查等工作。
垃圾回收器
- GC(Garbage Collection)是CLR中一种针对托管堆自动回收释放内存的服务。
- GC线程从栈中的引用开始跟踪,从而判定哪些内存是正在使用的,若GC无法跟踪到某一块堆内存,那么就认为这块内存不再使用了,即为可回收的。
编译运行过程
源代码.cs --> CLS编译 --> CIL(通用中间语言)(.exe, .dll) --> CLR编译、申请空间从逻辑上进行划分堆栈等、运行 --> 机器码
通用类型系统CTS(Common Type System)是.NET框架中的一个组成部分,为所有面向.NET框架的语言定义了数据类型的规则。
C#
Microsoft专为.NET推出的高级编程语言。
Mono
Novell 公司支持在其他操作系统下开发.NET 程序的框架。
Unity借助Mono实现跨平台,核心是.NET Framework框架。
2. Hello World
using System;
namespace Day01
{
class Program
{
static void Main(string[] args)
{
Console.Title = "My First Program";
// comment
Console.WriteLine("Hello World!");
string input = Console.ReadLine();
Console.WriteLine(input);
}
}
}
3. 变量
容量的单位
- 位bit
- 字节Byte
整型
- 1个字节:有符号sbyte (-128~127),无符号byte (0~255).
- 2个字节:有符号short (-32768~32767),无符号ushort (0~65535).
- 4个字节:有符号int,无符号uint.
- 8个字节:有符号long,无符号ulong.
非整型(小数)
4字节:单精度浮点类型float,精度7位。
1.2f
8字节:双精度浮点类型double,精度15-16位。
1.2d
16字节:128位数据类型decimal,精度28-29位,适用于财务和货币计算。对于精度较高的场合可以使用decimal。
1.2m
注意事项:
非整型变量赋值要加上后缀,如果不加默认为double。
浮点型运算会出现舍入误差:
bool number = 1.0f - 0.9f == 0.1f;
非数值型
- char 字符,2字节,存储单个字符,使用单引号。
- string 字符串,存储文本,使用双引号。
- bool类型,1字节,可以直接赋值true 真和false 假,或者赋表达式做判断。
4. 语法
变量命名使用小驼峰。string studentName;
数组的声明方式
int[] arr1 = new int[1];
int[,] arr2 = new int[1,2];
交错数组
列大小不确定的数组。
// 创建具有4个元素的交错数组
int[][] arr = new int[4][];
// 创建一维数组,赋值给交错数组的第i个元素
arr[0] = new int[3];
arr[1] = new int[5];
arr[2] = new int[4];
arr[3] = new int[1];
// 将数字n赋值给交错数组的第i个元素的第j个元素
arr[0][0] = 1;
arr[1][2] = 2;
传递数组的方式
params 参数数组:使用params关键字后,对于方法内部而言,就是个普通数组。对于方法外(调用者)而言,可以传递数组,也快吃传递一组数据类型相同的变量集合,甚至可以不传递参数。
类似Java的可变形参String ... args
。
int[] arr = new int[]{1, 23, 3, 5};
Add(arr);
Add(1, 23, 3, 5);
Add();
private static int Add(params int[] arr)
{
int sum = 0;
foreach (var item in arr)
{
sum += item;
}
return sum;
}
引用传递
传递实参变量自身的内存地址
在传入之前必须赋值
private static void Fun(ref int a, ref int b) {
int temp = a;
a = b;
b = temp;
}
// 需要赋值后才可传入
int a = 1, b = 2;
Fun(ref a, ref b);
输出传递
传递实参变量自身的内存地址
控制离开方法之前必须对out参数进行赋值
private static void Fun(ref int length, ref int width, out int area, out int perimeter) {
// 方法内部必须为参数赋值
area = length * width;
perimeter = (length + width) * 2;
}
int length = 1, width = 2, area, perimeter;
Fun(ref length, ref width, out area, out perimeter);
var类型推断
根据所赋数据判断类型
var v1 = 1;
var v2 = true;
string.Format 字符串格式化
占位符
string str = string.Format("枪的名称为:{0},容量为:{1}", gunName, ammoCapacity);
Console.WriteLine(str);
// c | C:货币格式
// d | D:十进制格式
// e | E:科学计数(指数)格式
// f | F:浮点格式
// x | X:十六进制格式
// p | P: 百分比格式
// $10.00
Console.WriteLine("{0:c}", 10);
// 05
Console.WriteLine("{0:d2}", 5);
// 以指定精度四舍五入
// 1.2
Console.WriteLine("{0:f1}", 1.23);
// 10.000%
Console.WriteLine("{0:p}", 0.1);
// 空字符表示
char c = '\0';
// \r\n 回车换行
Console.WriteLine("Hello, \r\n world!");
// 从字符串中获取字符
char c1 = str[0];
运算符
// 赋值表达式自身也有值,其值为所赋值
int n1, n2;
n1 = n2 = 1;
// n1 == n2 == 1
类型转换
// Parse转化:string 转化为其他的数据类型
string strNumber = "18";
int num = int.Parse(strNumber);
float num2 = float.Parse(strNumber);
// 任意类型转string
string s1 = num.ToString();
隐式转换和强制转换和Java相同。
4.1. 流程控制
swich-case 中的case有操作,则不支持贯穿到后面的case或default,必须使用break跳出。
if-else if-else, switch, for, while-do, do-while和Java大同小异。
foreach
int[] arr = new int[] { 1, 2, 3, 4 };
foreach(int val in arr)
{
Console.WriteLine(val);
}
4.2. 方法
方法名首字母大写,采用大驼峰的写法。
返回的数据必须与返回值类型兼容(可以自动隐式转换)。
/// <summary>
/// 根据年月日,计算星期数的方法
/// </summary>
/// <param name="year"></param>
/// <param name="month"></param>
/// <param name="day"></param>
/// <returns></returns>
private static int GetWeekByDay(int year, int month, int day)
{
DateTime dateTime = new DateTime(year, month, day);
return (int)dateTime.DayOfWeek;
}
数组常用方法及属性
数组长度:
数组名.Length
清除元素值:
Array.Clear
复制元素:
Array.Copy
数组名.CopyTo
克隆:
数组名.Clone
查找元素:
Array.IndexOf
Array.LastIndexOf
排序:
Array.Sort
反转:
Array.Reverse
判断是否为同一个引用
bool flag = object.ReferenceEquals(s1, s2);
4.3. 类
object 是所有类的父类
object o1 = 1;
object o2 = "2";
Array是数组的父类
Array arr1 = new int[2];
Array arr2 = new double[2];
对象
using System;
namespace Main
{
public class Person
{
// 私有字段配置公开属性,类似于Java的Getter和Setter
// 字段:存储数据
private string name;
// 属性:保护字段
public string Name
{
// 本质就是Java中的Getter和Setter
// 读取时保护
get
{
return name;
}
// 写入时保护
set
{
// 用value关键字表示要设置的数据
this.name = value;
}
}
}
}
简写(.NET3.0):
// 自动属性:包含1个字段 2个方法
public int Age { get; set; }
构造函数
public Person()
{
}
// 在构造函数里面调用其他构造函数
public Person(string name) : this()
{
this.Name = name;
}
继承
// 继承Person类
public class Student : Person {
}
4.4. 枚举
using System;
namespace Main
{
// 默认为int,可显式指定
// public enum MoveDirection : int
public enum MoveDirection
{
UP = 0,
DOWN = 1,
LEFT = 2,
RIGHT = 3,
}
}
多个枚举值做或运算实现多选,这要求:
做或运算的结果不能与其他枚举的值相同,即当个只在某一个位上为1,且不与其他枚举相同。
定义枚举的时候,使用
[Flags]
修饰。[Flags]
表示可以将枚举作为位域(即一组标志处理)。最后做判断的时候,将传入的值与枚举值逐个做与运算,可得出是否包含该枚举值。
using System;
namespace Main
{
[Flags]
public enum MoveDirection
{
UP = 0,
DOWN = 1,
LEFT = 2,
RIGHT = 4,
}
}
//
move(MoveDirection.UP | MoveDirection.Down);
private static void move(MoveDirection direction)
{
if ((dorection & MoveDirection.UP) != 0) {
//...
}
}
数值类型转换
Print(MoveDirection.Left);
// int <==> enum
// 使用强制类型转换实现
Print((MoveDirection) 2);
int num = (int) MoveDirection.Left;
// string ==> enum
MoveDirection direction = (MoveDirection) Enum.Parse(typeof(MoveDirection), "LEFT");
// enum ==> string
String str = MoveDirection.LEFT.ToString();
4.5. 集合
List是一个类,可以直接new。List根据索引获取元素。
List<string> list = new List<string>();
list.Add("test");
string str = list[0];
字典集合Dictionary(Map)。字典根据key获取元素,用中括号。
Dictionary<string, int> dic = new Dictionary<string, int>();
dic.Add("test", 0);
int i1 = dic["test"];
5. 数据类型
- 值类型
- 结构
- 数值类型
- bool
- char
- 枚举
- 结构
- 引用类型
- 接口
- 类
- string
- Array
- 委托
6. IDE
6.1. Visual Studio
region和endregion
其作用是将一段代码标记为给定名称的块,当代码量比较大的时候,可以方便地实现代码的管理。可以将代码折叠,只显示注释。
不属于C#语法。
#region 从字符串中获取字符
char c2 = str[1];
#endregion
调试步骤
- 在可能出错的行加断点。
- 按F5 启动调试。
- 按F11逐语句执行。
- 按Shift + F5 停止调试。
其他
prop
+ tab = public object MyProperty { get; set; }